@file:Suppress("unused", "DEPRECATION")

package com.hjh.tool.util

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.wifi.WifiManager
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.annotation.RequiresPermission
import com.elvishew.xlog.XLog
import java.io.File
import java.net.Inet4Address
import java.net.NetworkInterface
import java.util.Locale
import kotlin.collections.find
import kotlin.collections.firstOrNull
import kotlin.collections.flatMap
import kotlin.collections.forEach
import kotlin.collections.toList
import kotlin.io.useLines
import kotlin.let
import kotlin.sequences.drop
import kotlin.sequences.firstOrNull
import kotlin.sequences.mapNotNull
import kotlin.text.contains
import kotlin.text.format
import kotlin.text.split

object NetworkQueryHelper {

    /**
     * 查找指定传输类型的网络
     */
    @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
    fun getNetworkByTransport(context: Context, transport: Int): Network? {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        return cm.allNetworks.firstOrNull {
            cm.getNetworkCapabilities(it)?.hasTransport(transport) == true
        }
    }

    /**
     * 获取当前设备 IP 地址，按网络类型区分
     */
    fun getIpByNetworkType(context: Context, type: NetworkType): String? {
        return when (type) {
            NetworkType.WIFI -> getWifiIp(context)
            NetworkType.ETHERNET -> getEthernetIp()
            else -> getActiveNetworkIp(context)
        }
    }

    /**
     * 获取指定 Network 的 IP 地址
     */
    fun getIpFromNetwork(context: Context, network: Network?): String? {
        if (network == null) return null
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val props = cm.getLinkProperties(network) ?: return null
        return props.linkAddresses.firstOrNull {
            it.address is Inet4Address && !it.address.isLoopbackAddress
        }?.address?.hostAddress
    }

    /**
     * 获取当前活动网络的IP地址，兼容所有安卓版本。
     *
     * @param context 上下文
     * @return IP地址字符串，如果无活动网络或无法获取则返回 null。
     */
    @Suppress("DEPRECATION") // 允许为旧版系统使用弃用的API
    fun getActiveNetworkIp(context: Context): String? {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

        // 对于 Android 6.0 (API 23) 及以上版本
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val network = cm.activeNetwork ?: return null
            val capabilities = cm.getNetworkCapabilities(network) ?: return null
            // 确保网络是有效的（例如，已连接到互联网）
            if (!capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
                return null
            }
            val props = cm.getLinkProperties(network) ?: return null
            return props.linkAddresses.firstOrNull {
                it.address is Inet4Address && !it.address.isLoopbackAddress
            }?.address?.hostAddress
        } else {
            // 对于低于 Android 6.0 的版本 (包括 SDK 21)
            val activeNetworkInfo = cm.activeNetworkInfo
            if (activeNetworkInfo != null && activeNetworkInfo.isConnected) {
                try {
                    // 遍历所有网络接口
                    val networkInterfaces = NetworkInterface.getNetworkInterfaces()
                    while (networkInterfaces.hasMoreElements()) {
                        val iface = networkInterfaces.nextElement()
                        val enumIpAddress = iface.inetAddresses
                        while (enumIpAddress.hasMoreElements()) {
                            val inetAddress = enumIpAddress.nextElement()
                            // 过滤掉回环地址并确保是IPv4地址
                            if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) {
                                return inetAddress.hostAddress
                            }
                        }
                    }
                } catch (ex: Exception) {
                    // 异常处理
                    ex.printStackTrace()
                }
            }
        }
        return null
    }

    /**
     * 遍历路由文件获取 IP（兼容方案）
     */
    fun getIpFromRoutingTable(): String? {
        return try {
            File("/proc/net/route").useLines { lines ->
                lines.drop(1).mapNotNull {
                    val parts = it.split("\t")
                    if (parts.size > 1 && parts[1] == "00000000") parts[0] else null
                }.firstOrNull()
            }?.let { face ->
                NetworkInterface.getByName(face)?.inetAddresses?.toList()
                    ?.firstOrNull { it is Inet4Address && !it.isLoopbackAddress }
                    ?.hostAddress
            }
        } catch (e: Exception) {
            XLog.e("路由表获取 IP 失败: ${e.message}")
            null
        }
    }

    /**
     * 获取第一个可用的 IPv4 地址（不包括回环地址）
     */
    fun getFirstAvailableIp(): String? {
        return try {
            NetworkInterface.getNetworkInterfaces().toList().flatMap {
                it.inetAddresses.toList()
            }.firstOrNull { it is Inet4Address && !it.isLoopbackAddress }?.hostAddress
        } catch (e: Exception) {
            XLog.e("遍历网络接口获取 IP 失败: ${e.message}")
            null
        }
    }

    /**
     * 判断指定类型网络是否可用
     */
    @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
    fun isNetworkTypeAvailable(context: Context, type: NetworkType): Boolean {
        return type.transport?.let { getNetworkByTransport(context, it) != null } == true
    }

    /**
     * 获取当前所有可用的网络类型
     */
    @OptIn(ExperimentalStdlibApi::class)
    fun getAvailableNetworkTypes(context: Context): List<NetworkType> {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val list = mutableListOf<NetworkType>()
        cm.allNetworks.forEach { network ->
            val caps = cm.getNetworkCapabilities(network) ?: return@forEach
            NetworkType.values().forEach {
                if (it.transport != null && caps.hasTransport(it.transport)) {
                    list.add(it)
                }
            }
        }
        return list
    }

    private fun getWifiIp(context: Context): String? {
        val wifiManager =
            context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val ip = wifiManager.connectionInfo.ipAddress
        return if (ip != 0) {
            String.format(
                Locale.CHINA,
                "%d.%d.%d.%d",
                ip and 0xFF,
                ip shr 8 and 0xFF,
                ip shr 16 and 0xFF,
                ip shr 24 and 0xFF
            )
        } else null
    }

    private fun getEthernetIp(ethName: String = "eth"): String? {
        return try {
            NetworkInterface.getNetworkInterfaces().toList()
                .find { it.displayName.contains(ethName, ignoreCase = true) }
                ?.inetAddresses?.toList()
                ?.firstOrNull { it is Inet4Address && !it.isLoopbackAddress }
                ?.hostAddress
        } catch (e: Exception) {
            XLog.e("获取以太网 IP 失败: ${e.message}")
            null
        }
    }

    enum class NetworkType(val transport: Int?) {
        ETHERNET(NetworkCapabilities.TRANSPORT_ETHERNET),
        WIFI(NetworkCapabilities.TRANSPORT_WIFI),
        CELLULAR(NetworkCapabilities.TRANSPORT_CELLULAR),
        VPN(NetworkCapabilities.TRANSPORT_VPN),
        BLUETOOTH(NetworkCapabilities.TRANSPORT_BLUETOOTH),
        @RequiresApi(Build.VERSION_CODES.O_MR1)
        LOWPAN(NetworkCapabilities.TRANSPORT_LOWPAN),

        @SuppressLint("InlinedApi")
        USB(NetworkCapabilities.TRANSPORT_USB),
        @RequiresApi(Build.VERSION_CODES.O)
        WIFI_AWARE(NetworkCapabilities.TRANSPORT_WIFI_AWARE),
        ANY(null)
    }
}

